<?php
namespace Admin\Service;

/**
 * 客户管理后台服务
 */

use Admin\Model;

class CustomerService
{
    private $m_ret = array('rcode'=>0, 'data'=>NULL, 'msg'=> 'Internal Error');

    //根据客户资料注册新用户
    public function register( $_Info )
    {
        $res = $this->m_ret;
        if( !$_Info || !isset( $_Info['customer_name'] ) || !$_Info['customer_name']) {
            $res['msg'] = "客户的注册信息不能为空";
        }
        else{
            if( !$_Info['sales_person']  || !$_Info['sales_manager'] || !$_Info['sales_sub_company']){
                $res['msg'] = "客户的注册信息不完整";
            }
            else{
                $MUser = D('Admin/User');
                $MCustomer = D('Admin/Customer');
                $regInfo = array();
                $regInfo['nickname'] = trim( $_Info['customer_name'] );
                $where = array();
                $where['nickname'] = array('eq', $regInfo['nickname'] );
                $login_count = $MCustomer->where( $where )->count() ;
                if( $login_count ){
                    $login_name = $regInfo['nickname'].'A'.$login_count;
                    $where['login_name'] = array('eq', $login_name);
                    $cnt = $MCustomer->where( $where )->count();
                    if ( !$cnt )
                        $regInfo['login_name'] = $login_name;
                    else
                        $regInfo['login_name'] = str_pad( $login_name, $cnt, 'A', STR_PAD_LEFT);
                }
                else
                    $regInfo['login_name'] = $regInfo['nickname'];
                $regInfo['remark'] = $_Info&&isset($_Info['remark']) ? $_Info['remark'] : '';
                $regInfo['phone'] = $_Info['phone'] ? $_Info['phone'] : NULL ;
                $regInfo['weixin_id'] = $_Info['weixin_id'] ? $_Info['weixin_id'] : NULL;
                $regInfo['qq'] = $_Info['qq'] ? $_Info['qq'] : NULL;
                $regInfo['mount'] =  $_Info['customer_mount']  ?  intval($_Info['customer_mount']) : 0;
                $regInfo['sex'] = $_Info['sex']  ? $_Info['sex']:0;
                $findRepeat = $this->findCount( $regInfo['nickname'], $regInfo['sales_manager'], $regInfo['phone'], $regInfo['qq'], $regInfo['weixin_id'] );
                if( $findRepeat &&  $findRepeat['data']>0 ){
                    $res['msg'] = "注册客户已经在系统客户存在";
                    return $res;
                }

                //客户编码
                $sales = '';
                $sales_person = $MUser->where( $whereu )->find();
                $regInfo['address'] = $_Info['addr'];
                $regInfo['sales_person'] = $_Info['_data']['sales']['user_id'];
                $regInfo['sales_sector'] = $_Info['_data']['sales']['sector_id'];
                $regInfo['sales_manager'] = $_Info['_data']['manager']['user_id'];
                $regInfo['sales_sub_company'] = $_Info['_data']['team'];

                if( !$regInfo['sales_person']  || !$regInfo['sales_manager'] || !$regInfo['sales_sub_company'] ){
                    $res['msg'] = "客户关联业务人员、经理或者分公司不存在";
                    return $res;
                }
                //自动填充字段
                $stime = isset($_Info['pay'])&&$_Info['pay']&&isset($_Info['pay']['pay_time'])  ? $_Info['pay']['pay_time']:FALSE;
                $regInfo['create_time'] = $stime ? date('Y-m-d H:i:s', strtotime($stime)) : date('Y-m-d H:i:s');
                $regInfo['last_time'] = date('Y-m-d H:i:s');
                $regInfo['develop_times'] = 0;
                $regInfo['pass'] = md6('123456'.$regInfo['create_time']);
                $regInfo['state'] = \Admin\Model\CustomerModel::STATE_NORMAL;
                $regInfo['stock_account_state'] = 0;

                //生成客户编码
                $regInfo['customer_code'] = $this->code();
                $regRet = $MCustomer->data( $regInfo )->add();
                if( $regRet ){
                    //phone,注册成功，处理电话号码的问题
                    $res['rcode'] = 1;
                    $res['data'] = $regRet;
                    $res['msg'] = 'OK';
                    if( $regInfo['phone'] )
                        $this->addPhone( $regRet, $regInfo['phone'] );
                }
                else
                    $res['msg'] = "客户信息注册失败";
            }
        }

        return $res;
    }

    //电话记录增加记录
    public function addPhone( $_customer_id,  $_phone, $_main = FALSE )
    {
        $MBook = D('Admin/CustomerPhonebook');
        $wheres = array();
        $cnt = 0;
        if( !$_phone )
            return FALSE;
        $wheres['book_phone'] = array('eq', $_phone );
        $cnt = $MBook->where( $wheres )->count();
        if( $cnt ){
            return FALSE;
        }
        else{
            $wheres = array();
            $wheres['customer_id'] = array('eq', $_customer_id);
            $cnt = $MBook->where( $wheres )->count();
            if( $cnt && $_main ){
                $dup = array();
                $dup['is_main']  = 0;
                $MBook->where( $wheres )->save( $dup );
            }
            else if( !$cnt ){
                $_main = TRUE;
            }

            $data = array();
            $data['book_phone'] = $_phone;
            $data['customer_id'] = $_customer_id;
            $data['is_use'] = 1;
            $data['is_main'] = $_main ? 1 : 0;
            return $MBook->data( $data )->add();
        }
    }

    //更新合同是否需要回访状态
    public function updateContractVisit( $_cid, $_status){
        $MContract = D('Admin/Contract');
        $wheres = array();
        $wheres['contract_id'] = array('eq', $_cid);
        if( !$MContract->where( $wheres )->find() ){
            return FALSE;
        }
        else{
            $dup = array();
            $dup['need_return_visit'] = $_status;
            return $MContract->where( $wheres )->save( $dup );
        }
    }

    /**
     *根据Excel付款序列号、付款时间判断是否重复付款
     * @param  string $serial_no  Excel序列号
     * @param  string $pay_time   付款时间
     * @return FALSE/0/1   返回结果 FALSE表示发生错误
     */
    public function oneExcelPay($serial_no, $pay_time, $pay_way=false, $pay_order=false)
    {
        if( !$serial_no || !$pay_time )
            return FALSE;
        $MPay = D('Admin/PayRecord');
        $wheres = array();
        $st = strtotime( $pay_time );
        //
        $wheres['excel_order'] = array('eq', $serial_no);
        $wheres['pay_time'] = array('eq', date('Y-m-d 0:0:0', $st ));
        $cnt = $MPay->where( $wheres )->count();
        if( $cnt )
            return 1;
        else {
            if ($pay_way && $pay_order) {
                $wheres = array();
                $wheres['pay_way'] = array('eq', $pay_way);
                $wheres['pay_order'] = array('eq', $pay_order);
                $cnt = $MPay->where( $wheres )->count();
                if ($cnt) return $cnt;
            }
            return 0;
        }
    }

    //添加付款信息
    public function addPay($_customer_id, $_contract_id, $_payInfo, $_ext = false)
    {
        $MPay = D('Admin/Pays');
        $MCon = D('Admin/Contract');
        $MUser = D('Admin/User');
        $data = array();
        $wheres = array();
        $data['pay_mount'] = $_payInfo['mount'];
        $data['pay_name'] = $_payInfo['pay_name'];
        $data['pay_way'] = $_payInfo['pay_way'];
        $data['pay_order'] = $_payInfo['order_number'];
        $pt = strtotime( $_payInfo['pay_time'] );
        $data['pay_time'] = date('Y-m-d 0:0:0', $pt );
        $data['excel_order'] =  $_payInfo['order']  ?  $_payInfo['order'] :'';
        $data['remark'] = $_payInfo&&isset($_payInfo['remark']) ? $_payInfo['remark'] : '';

        $data['customer_id'] = $_customer_id;
        $data['contract_id'] = $_contract_id;

        //业绩归属人信息
        $wherec = array();
        $wherec['contract_id'] = array('eq', $_contract_id );
        $data['is_conflict'] = 0;
        $dcon = $MCon->where( $wherec )->find();

        //添加人默认为查账流水导入人员,如果从接口提交默认是续费人员
        $uinfo = \Admin\Model\UserModel::loadFromSession();
        if (!$uinfo){
            $uinfo = $_ext['sales'];
        }
        $data['creator'] = $uinfo['user_id'];
        $data['creator_sector'] = $uinfo['sector_id'];

        $data['sales_person'] = $_ext['sales']['user_id'];
        $data['sales_sector'] = $_ext['sales']['sector_id'];
        $data['sales_manager'] = $_ext['manager']['user_id'];
        $data['sales_sub_company'] = $_ext['team'];
        $data['customer_product'] = $_ext['product'];

        //根据付款人员以及当时的经理进行判断是否撞单
        if( $data['sales_manager'] ){
            $wheres = array();
            $wheres['record_status'] = array('eq', \Admin\Model\PaysModel::RECORD_STATUS_VALID);
            $wheres['audit_res'] = array('eq', \Admin\Model\PaysModel::AUDIT_OK);
            $wheres['customer_id'] = array('eq', $_customer_id);
            $lastPayManagerId = $MPay->where( $wheres )->order('pay_time desc')->getField('sales_manager');
            //前后两次付款人员经理不一样，可能发生撞单
            if( $lastPayManagerId && $lastPayManagerId != $_ext['manager']['user_id'] )
                $data['is_conflict'] = 1;
        }
        $data['audit_res'] = \Admin\Model\PaysModel::AUDIT_OK;
        //增加支付线上、线下支付类型,线下支付需要人工去审核
        if (isset($_payInfo['pay_type']) && $_payInfo['pay_type'] == \Admin\Model\PaysModel::PAY_OFFLINE){
            $data['audit_res'] = \Admin\Model\PaysModel::AUDIT_NEED;
        }
        $data['create_time'] = date('Y-m-d H:i:s');
        $data['record_status'] = \Admin\Model\PaysModel::RECORD_STATUS_VALID;

        //进行重复判断,重复添加默认处理
        if( $data['excel_order'] ){
            $find = $this->oneExcelPay( $data['excel_order'], $data['pay_time'], $data['pay_way'], $data['order_number']);
            if( $find )
                return TRUE;
        }

        $pid = $MPay->data( $data )->add();
        if( $pid ){
            $dup = array();
            $wherep = array();
            $wherep['payrecord_id'] = array('eq', $pid);
            $dup['pay_id'] = $pid;
            $MPay->where( $wherep )->save( $dup );
            //进行合同违规判断
            if( isset( $_payInfo['is_weigui'] ) && $_payInfo['is_weigui'] ){
                //违规撞单暂时不处理
            }
            //合同签订天数更新
            $wherep = array();
            $wherep['contract_id'] = array('eq', $_contract_id );
            $wherep['record_status'] = array('eq', \Admin\Model\PaysModel::RECORD_STATUS_VALID);
            $wherep['pay_time'] = array('gt', $data['pay_time']);
            $findCount = $MPay->where( $wherep )->count();
            if (!$findCount) {
                $wherec = array();
                $wherec['contract_id'] = array('eq', $_contract_id );
                $datediff = time() - $pt;
                $contractSign = array();
                $contractSign['sign_day'] = floor($datediff / (60 * 60 * 24));
                $MCon->where( $wherec )->save( $contractSign );
            }
            return TRUE;
        }
        else
            return FALSE;
    }

    private function _contractOrder( $payWay )
    {
        $Mdo = D('Admin/Contract');
        $payWay = trim($payWay);
        $payParse = preg_split('/(?<!^)(?!$)/u', $payWay );
        $contract_number = '';
        $contract_number = ff_letter_first( $payParse[0]).ff_letter_first( $payParse[1]).'-'.date('Y').'-HT-';
        $wheres = array();
        $wheres['order_num'] = array('like', $contract_number.'%');
        $cnt  = $Mdo->where( $wheres )->count();
        if( FALSE === $cnt )
            $cnt = 0;
        $cnt++;
        $contract_number .= sprintf("%'.06d", $cnt);

        return $contract_number;
    }

    //合同甲方内容
    private function _contractFirstParty( $payWay )
    {
        $_firstData = array();
        $addrs = array(
                '北京和众汇富咨询有限公司天津分公司' => '天津自贸区（中心商务区）响螺湾旷世国际大厦A座1704-587号',
                '北京和众汇富咨询有限公司' => '北京市海淀区上地三街金隅嘉华大厦A座806',
                '北京和众汇富咨询有限公司山东分公司' => '山东省济南市市中区经四路5号万达广场C座1403',
                );
        $MParam =  D('Admin/SysParam');
        $MParamDetail = D('Admin/SysParamDetail');
        $wheres = array();
        $wheres['p.key_name'] = array('eq', 'PAY_WAY');
        $wheres['sp.detail_name'] = array('eq', $payWay );
        $payData = $MParam->alias("p")
                          ->field("sp.detail_value as v")
                          ->join("LEFT JOIN sys_param_detail sp on sp.sys_param_id=p.sys_param_id")
                          ->where( $wheres )
                          ->find();
        $addr = '';
        if( $payData ) {
            $psub = $payData['v'];
            $psub = explode('|', $psub );
            $key = trim($psub[0]);
            $addr = $psub&&isset($addrs[$key]) ? trim($addrs[$key]) : '';
            $_firstData['first_party_address'] = $addr;
            $_firstData['first_party_name'] = $key;
            $_firstData['first_party_bank_account'] = trim($psub[1]);
            $_firstData['first_party_bank_deposit'] = trim($psub[2]);
        }
        else {
            $_firstData['first_party_address'] = '';
        }
        return $_firstData;
    }

    /**
     * 根据客户ID、合同金额、开始时间、合同时长、地址、扩展信息注册合同
     * 
     * @param int    $_customer_id       客户信息ID
     * @param float  $_mount             合同金额
     * @param string $_stime             合同开始时间
     * @param string $_service           合同服务期限
     * @param string $_addr              合同地址
     * @param array  $_ext               扩展信息
     * 
     * @return  int/FALSE   合同ID 
     * 
    */
    public function addContract( $_customer_id, $_mount, $_stime, $_service, $_addr, $_ext ){
        $MContract = D('Admin/Contract');
        $data = array();
        $data['customer_id'] = $_customer_id;

        /**
         * 自助服务系统增加订单判断，一个合同对应一个订单
         * 
        */
        if ($_ext && isset($_ext['order_number'])&&$_ext['order_number']){
            $whereZiZhu = array();
            $whereZiZhu['zizhu_pay_order'] = array('eq', $_ext['order_number']);
            $find = $MContract->where( $whereZiZhu )->count();
            if ($find){//如果已经存在，则直接返回失败
                return FALSE;
            }
        }
        $MCustomer = D('Admin/Customer');
        $MUser = D('Admin/User');

        $dataCustomer = $MCustomer->where('customer_id='.$_customer_id)->find();
        $data['product_id'] = $_ext['product'];
        $data['sales_person'] = $_ext['sales']['user_id'];
        $data['sales_sector'] = $_ext['sales']['sector_id'];
        $data['sales_manager'] = $_ext['manager']['user_id'];
        $data['sales_sub_company'] =$_ext['team'];
        if ($_ext && isset($_ext['order_number'])){
            $data['zizhu_pay_order'] = $_ext['order_number'];
        }
        if( $_addr )
            $data['address'] = $_addr;
        if (isset($_ext['survey_code']) && $_ext['survey_code'])
            $data['survey_code'] = $_ext['survey_code'];
        $data['mount'] =  doubleval( $_mount );
        $st = strtotime( $_stime );
        $data['start_time'] = date('Y-m-d 0:0:0', $st );
        /**
         * BUG fix:合同期限小数点的问题，统一单位为月
        */
        if ($_service) {
            if (preg_match('#\.#', $_service)) {
                $arrMonth = explode('.', $_service);
                $contractEndTime = strtotime("+".$arrMonth[0]." month", $st );
                if (isset($arrMonth[1])&&$arrMonth[1]) {
                    ##TODO 一个月暂时按照30天计算
                    $days = 3*$arrMonth[1];
                    $contractEndTime = strtotime("+".$days." day", $contractEndTime);
                }
                $data['end_time'] = date('Y-m-d 23:59:59',  $contractEndTime);
            }
            else {
               $data['end_time'] = date('Y-m-d 23:59:59', strtotime("+".$_service." month", $st )) ;
            }  
        }
        else {
            $data['end_time'] = date('Y-m-d', strtotime("+1 year", $st));
        }
        
        $data['create_time'] = date('Y-m-d H:i:s');
        $data['need_return_visit'] = 1;
        $data['weigui_status'] = \Admin\Model\ContractModel::WEIGUI_STATUS_UNKNOWN; //未处理违规
        $data['sign_status'] = \Admin\Model\ContractModel::SIGN_NO; 
        $data['is_need_combine'] = 0;
        $data['is_delete'] = 0;
        $data['price_id'] = 0;
        $data['type'] = 1;//合同默认为电子合同
        $data['state'] = \Admin\Model\ContractModel::STATE_NEED_AUTH;

        //合同订单号
        $data['order_num'] = $this->_contractOrder( $_ext['pay']['pay_way']);
        //合同甲方乙方内容
        $firstParty = $this->_contractFirstParty( $_ext['pay']['pay_way'] );
        $data = array_merge($data, $firstParty);
        $data['second_party_phone'] = $dataCustomer['phone'];
        $data['second_party_name'] = $dataCustomer['nickname'];
        $data['second_party_address'] = $_addr;
        //判断合同是否需要进行合并处理,并做出提示
        $wherep = array();
        $wherep['customer_id'] = array('eq', $_customer_id);
        $wherep['state'] = array('in', array(0, \Admin\Model\ContractModel::STATE_SERVICE) );
        $wherep['is_delete'] = array('neq', 1);
        $wherep['end_time'] = array('gt', date('Y-m-d 23:59:59') );
        $cnt = $MContract->where( $wherep )->count();
        if( $cnt ){
            $data['is_need_combine'] = 1;
        }

        //根据产品的投顾老师获取 投顾老师的显示名称以及编号
        $wherep = array();
        $wherep['p.product_id'] = array('eq', $_ext['product']);
        $MProduct = D('Admin/Product');
        $teacherCert = $MProduct->alias('p')
                                ->field("u.teacher_name,u.cert_num")
                                ->join("LEFT JOIN user u on u.user_id=p.manager_id")
                                ->where( $wherep )
                                ->find();
        if ($teacherCert) {
            $data['teacher_name'] = $teacherCert['teacher_name'];
            $data['teacher_cert'] = $teacherCert['cert_num'];
        }

        $conid = $MContract->data( $data )->add();
        //更新客户的保护期
        if( $conid ){
            $st = strtotime( $data['end_time'] );
            $upProtectTime = array();
            $upProtectTime['protect_time']  = date('Y-m-d H:i:s', strtotime("+3 month", $st));
            $wherecu = array();
            $wherecu['customer_id'] = array('eq', $_customer_id);
            //只更新比当前客户保护时间大的保护期
            $wherecu['protect_time'] = array('lt', $upProtectTime['protect_time']);
            $MCustomer->where( $wherecu )->save( $upProtectTime );

            $_wherec = array();
            $_wherec['contract_id'] = array('eq', $conid );
            $d = $MContract->where( $_wherec )->find();
        }

        return $conid ? $conid : FALSE;
    }

    /**
     * 客户合并
     *
     * @param  int $_from    是将哪个客户合并
     * @param  int $_to      是将客户合并到那个客户
     * @return array         array('rcode'=>0/1,'msg'=>'错误信息',data)
     */
    public function combineTo( $_from, $_to )
    {
        $res = $this->m_ret;
        $MCustomer = D('Admin/Customer');
        if( !$_from || !$_to ){
            $res['msg'] = "提交参数错误";
        }
        else{
            $fromCustomer = $this->findActiveCustomerById( $_from );
            $toCustomer = $this->findActiveCustomerById( $_to );
            if( $fromCustomer && $toCustomer ){
                $where = array();
                $where['customer_id'] =  array('eq', $fromCustomer['customer_id'] );
                $dup = array();
                $dup['combine_to'] = $toCustomer['customer_id'];
                $dup['state'] = \Admin\Model\CustomerModel::STATE_COMBINE;
                $dup['combine_time'] = date('Y-m-d H:i:s'); // 客户合并时间
                $upCount = $MCustomer->where( $where )->save( $dup );
                if( $upCount ){
                    $res['rcode'] = 1;
                    $res['data'] = $upCount;
                    $res['msg'] = 'OK';
                }
                else{
                    $res['msg'] = "客户合并失败";
                }
            }
            else{
                $res['msg'] = "该客户不能合并";
            }
        }
        return $res;
    }

    //根据一定规则生成客户编码
    public function code( $param = array() )
    {
        $MCustomer = D('Admin/Customer');
        $where = array();
        $stime = date('Y-01-01 0:0:0');
        $etime = date('Y-12-31 23:59:59');
        $where['create_time'] = array('between',array($stime,$etime));
        $count = $MCustomer->where( $where)->count();
        if (!$count)
            $count = 1;
        $count = !$count ? 1:($count+1);
        $code = 'AA_'.date('Y').'_'.$count;
        $where = array();
        $where['customer_code'] = array('eq', $code);
        $find = $MCustomer->where( $where )->count();
        if ($find){
            $code = $code.'_'.$find;
        }
        return  $code;
    }

    /**
     * 根据客户姓名、经理、电话、微信、QQ 等查询客户信息
     * 
     * @param string $_nickname         客户昵称
     * @param string $_manager          部门经理
     * @param string $_phone            电话
     * @param string $_qq               客户QQ
     * @param string $_weixin_id        客户微信ID 
     * 
     * @return array(
     *                  'data' => 0/1/more,匹配到的客户数量
     *                  'find' => array/false  匹配到的客户
     *                  'msg'  => 消息提示
     *                  )
    */
    public function findCount( $_nickname, $_manager,$_phone = FALSE , $_qq = FALSE , $_weixin_id = FALSE )
    {
        $res = $this->m_ret;
        $MUser = D('Admin/User');
        $MCustomer = D('Admin/Customer');

        $whereu = $wherec = $where_complex = array();
        if ($_phone){
            $MCustomerPhone = D('Admin/CustomerPhonebook');
            $wherep = array();
            $wherep['b.book_phone'] = array('eq', $_phone );
            $find = $MCustomerPhone->alias("b")
                                   ->field("c.*")
                                   ->join("left join customer c on c.customer_id=b.customer_id")
                                   ->where( $wherep )
                                   ->find();
            if ($find){
                $res['data'] = 1;
                $res['find'] = $find;
                $res['rcode'] = 0;
                $res['msg'] = 'OK';
                return $res;
            }
        }

        if( !$_nickname || !$_manager )
            return FALSE;
        $whereu['nickname'] = array('eq', $_manager );
        $manager_id = $MUser->where( $whereu )->getField("user_id");
        if( !$manager_id )
            return FALSE;
        $where_complex['nickname'] = array('eq', $_nickname );
        $where_complex['sales_manager'] = array('eq', $manager_id );
        $cnt = $MCustomer->where( $where_complex )->count();
        if( 1 == $cnt ){
            $res['data'] = 1;
            $res['msg'] = 'OK';
            $res['rcode'] = 0;
            $res['find'] = $MCustomer->where( $where_complex )->find();
            return $res;
        }
        /*没有其他信息无法判定客户是否唯一，默认创建客户*/
        if( !$_phone && !$_qq && !$_weixin_id )
            return FALSE;

        if( $_qq )
            $wherec['qq'] = array('eq', $_qq);
        if( $_weixin_id )
            $wherec['weixin_id'] = array('eq', $_weixin_id);

        if (count($wherec)){
            $wherec['_logic'] = 'OR';
            $where_complex['_complex'] = $wherec;
        }
        $where_complex['state'] = array('neq', \Admin\Model\CustomerModel::STATE_INVALID_USER );
        $where_complex['is_delete'] = array('neq', 1 );
        $res['data'] = $MCustomer->where( $where_complex )->count();
        if( $res['data'] !== FALSE ){
            if( 0 == $res['data'] )
                return FALSE;
            $res['rcode'] = 0;
            $res['msg'] = 'OK';
            if( $res['data'] == 1 )
                $res['find'] = $MCustomer->where( $wherec )->find();
            return $res;
        }
        else
            return FALSE;
    }

    //根据客户ID查询有效客户
    public function findActiveCustomerById( $_id )
    {
        $Mdo = D('Admin/Customer');
        $where = array();
        if( !$_id )
            return FALSE;
        $where['customer_id'] = array('eq', $_id );
        $where['is_delete'] = array('neq', 1);
        $where['state'] = array('in', array( \Admin\Model\CustomerModel::STATE_NEED_AUTH, \Admin\Model\CustomerModel::STATE_NORMAL) );//正常待审核状态的客户
        return $Mdo->where( $where )->find();
    }


    //更新客户资料
    public function update( $_customerID, $_updateInfo )
    {
        //
    }
}

